package org.weixin4j.third;

import com.alibaba.fastjson.JSONObject;
import org.weixin4j.WeixinException;
import org.weixin4j.third.model.*;
import org.weixin4j.util.WxHttpUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * 微信--token信息
 *
 * @author lizr
 */
public class WeixinThirdAPI {
    //获取预授权码
    private static String api_create_preauthcode_url = "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token=COMPONENT_ACCESS_TOKEN";
    private static String api_component_token_url = "https://api.weixin.qq.com/cgi-bin/component/api_component_token";
    private static String get_access_token_bycode_url = "https://api.weixin.qq.com/sns/oauth2/component/access_token?appid=APPID&code=CODE&grant_type=authorization_code&component_appid=COMPONENT_APPID&component_access_token=COMPONENT_ACCESS_TOKEN";
    private static String api_query_auth_url = "https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=COMPONENT_ACCESS_TOKEN";
    //客服接口地址
    private static String send_message_url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN";
    //4、获取（刷新）授权公众号的令牌
    private static String api_authorizer_token_url = "https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token=COMPONENT_ACCESS_TOKEN";
    //5、获取授权方的账户信息
    private static String api_get_authorizer_info_url = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token=COMPONENT_ACCESS_TOKEN";
    //6、获取授权方的选项设置信息
    private static String api_get_authorizer_option_url = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_option?component_access_token=COMPONENT_ACCESS_TOKEN";
    //7、设置授权方的选项信息
    private static String api_set_authorizer_option_url = "https://api.weixin.qq.com/cgi-bin/component/api_set_authorizer_option?component_access_token=COMPONENT_ACCESS_TOKEN";

    /**
     * 1、获取第三方平台access_token
     *
     * @return kY9Y9rfdcr8AEtYZ9gPaRUjIAuJBvXO5ZOnbv2PYFxox__uSUQcqOnaGYN1xc4N1rI7NDCaPm_0ysFYjRVnPwCJHE7v7uF_l1hI6qi6QBsA
     * @throws WeixinException
     */
    public static String getAccessToken(ApiComponentToken apiComponentToken) throws WeixinException {
        String component_access_token = "";
        String requestUrl = api_component_token_url;
        JSONObject result = WxHttpUtils.httpRequest(requestUrl, "POST", JSONObject.toJSONString(apiComponentToken));
        System.out.println("getAccessToken:" + result);
        if (result.containsKey("errcode")) {
            throw new WeixinException("获取第三方平台access_token！errcode=" + result.getString("errcode") + ",errmsg = " + result.getString("errmsg"));
        } else {
            component_access_token = result.getString("component_access_token");
        }
        return component_access_token;
    }

    /**
     * 2、获取预授权码
     *
     * @return kY9Y9rfdcr8AEtYZ9gPaRUjIAuJBvXO5ZOnbv2PYFxox__uSUQcqOnaGYN1xc4N1rI7NDCaPm_0ysFYjRVnPwCJHE7v7uF_l1hI6qi6QBsA
     * @throws WeixinException
     */
    public static String getPreAuthCode(String component_appid, String component_access_token) throws WeixinException {
        String pre_auth_code = "";
        String requestUrl = api_create_preauthcode_url.replace("COMPONENT_ACCESS_TOKEN", component_access_token);
        GetPreAuthCodeParam getPreAuthCodeParam = new GetPreAuthCodeParam();
        getPreAuthCodeParam.setComponent_appid(component_appid);
        JSONObject result = WxHttpUtils.httpRequest(requestUrl, "POST", JSONObject.toJSONString(getPreAuthCodeParam));
        System.out.println("getPreAuthCode:" + result);
        if (result.containsKey("errcode")) {
            throw new WeixinException("获取权限令牌信息！errcode=" + result.getString("errcode") + ",errmsg = " + result.getString("errmsg"));
        } else {
            pre_auth_code = result.getString("pre_auth_code");
        }
        return pre_auth_code;
    }

    /**
     * 3、使用授权码换取公众号的授权信息
     *
     * @return kY9Y9rfdcr8AEtYZ9gPaRUjIAuJBvXO5ZOnbv2PYFxox__uSUQcqOnaGYN1xc4N1rI7NDCaPm_0ysFYjRVnPwCJHE7v7uF_l1hI6qi6QBsA
     * @throws WeixinException
     */
    public static ReturnApiQueryAuthInfo getApiQueryAuthInfo(String component_appid, String component_access_token, String authorization_code) throws WeixinException {
        String requestUrl = api_query_auth_url.replace("COMPONENT_ACCESS_TOKEN", component_access_token);
        Map<String, String> mp = new HashMap<String, String>();
        mp.put("component_appid", component_appid);
        mp.put("authorization_code", authorization_code);
        System.out.println("-------------------3、使用授权码换取公众号的授权信息---requestUrl------------------------" + requestUrl);
        JSONObject result = WxHttpUtils.httpRequest(requestUrl, "POST", JSONObject.toJSONString(mp));
        System.out.println("getApiQueryAuthInfo:" + result);
        if (result.containsKey("errcode")) {
            throw new WeixinException("获取第三方平台access_token！errcode=" + result.getString("errcode") + ",errmsg = " + result.getString("errmsg"));
        }
        JSONObject authorizationInfoJSONObject = result.getJSONObject("authorization_info");
        authorizationInfoJSONObject.remove("func_info");//暂时去掉这么复杂的垃圾结构
        return JSONObject.toJavaObject(authorizationInfoJSONObject, ReturnApiQueryAuthInfo.class);
    }


    /**
     * 4、获取（刷新）授权公众号的令牌
     *
     * @param apiAuthorizerToken
     * @param component_access_token
     */
    public static ApiAuthorizerTokenRet apiAuthorizerToken(ApiAuthorizerToken apiAuthorizerToken, String component_access_token) throws WeixinException {
        String requestUrl = api_authorizer_token_url.replace("COMPONENT_ACCESS_TOKEN", component_access_token);
        JSONObject result = WxHttpUtils.httpRequest(requestUrl, "POST", JSONObject.toJSONString(apiAuthorizerToken));
        System.out.println("apiAuthorizerToken:" + result);
        return JSONObject.toJavaObject(result, ApiAuthorizerTokenRet.class);
    }

    /**
     * 5、获取授权方的账户信息
     */
    public static AuthorizerInfoResult apiGetAuthorizerInfo(ApiGetAuthorizer apiGetAuthorizer, String component_access_token) throws WeixinException {
        String requestUrl = api_get_authorizer_info_url.replace("COMPONENT_ACCESS_TOKEN", component_access_token);
        JSONObject result = WxHttpUtils.httpRequest(requestUrl, "POST", JSONObject.toJSONString(apiGetAuthorizer));
        System.out.println("apiGetAuthorizerInfo:" + result);
        JSONObject authorizationInfoJSONObject = result.getJSONObject("authorization_info");
        authorizationInfoJSONObject.remove("func_info");
        AuthorizationInfo authorizationInfo = JSONObject.toJavaObject(authorizationInfoJSONObject, AuthorizationInfo.class);

        JSONObject authorizerInfoJSONObject = result.getJSONObject("authorizer_info");
        JSONObject businessInfoJSONObject = authorizerInfoJSONObject.getJSONObject("business_info");
        BusinessInfo businessInfo = JSONObject.toJavaObject(businessInfoJSONObject, BusinessInfo.class);
        authorizerInfoJSONObject.remove("business_info");
        int serviceType = authorizerInfoJSONObject.getJSONObject("service_type_info").getIntValue("id");
        authorizerInfoJSONObject.remove("service_type_info");
        int verifyType = authorizerInfoJSONObject.getJSONObject("verify_type_info").getIntValue("id");
        authorizerInfoJSONObject.remove("verify_type_info");
        AuthorizerInfo authorizerInfo = JSONObject.toJavaObject(authorizerInfoJSONObject, AuthorizerInfo.class);
        authorizerInfo.setBusiness_info(businessInfo);
        authorizerInfo.setServiceType(serviceType);
        authorizerInfo.setVerifyType(verifyType);

        AuthorizerInfoResult authorizerInfoResult = new AuthorizerInfoResult();
        authorizerInfoResult.setAuthorization_info(authorizationInfo);
        authorizerInfoResult.setAuthorizer_info(authorizerInfo);
        return authorizerInfoResult;
    }

    /**
     * 6、获取授权方的选项设置信息
     */
    public static AuthorizerOptionRet apiGetAuthorizerOption(AuthorizerOption authorizerOption, String component_access_token) throws WeixinException {
        String requestUrl = api_get_authorizer_option_url.replace("COMPONENT_ACCESS_TOKEN", component_access_token);
        JSONObject result = WxHttpUtils.httpRequest(requestUrl, "POST", JSONObject.toJSONString(authorizerOption));
        System.out.println("apiGetAuthorizerOption:" + result);
        return JSONObject.toJavaObject(result, AuthorizerOptionRet.class);
    }

    /**
     * 7、设置授权方的选项信息
     */
    public static AuthorizerSetOptionRet apiSetAuthorizerOption(AuthorizerSetOption authorizerSetOption, String component_access_token) throws WeixinException {
        String requestUrl = api_set_authorizer_option_url.replace("COMPONENT_ACCESS_TOKEN", component_access_token);
        JSONObject result = WxHttpUtils.httpRequest(requestUrl, "POST", JSONObject.toJSONString(authorizerSetOption));
        System.out.println("apiSetAuthorizerOption:" + result);
        return JSONObject.toJavaObject(result, AuthorizerSetOptionRet.class);
    }
    /**
     * 微信主动推送给第三方服务器
     * 8、推送component_verify_ticket协议
     * 9、推送取消授权通知
     */


    /**
     * 获取第三方平台access_token
     *
     * @param appid
     * @return kY9Y9rfdcr8AEtYZ9gPaRUjIAuJBvXO5ZOnbv2PYFxox__uSUQcqOnaGYN1xc4N1rI7NDCaPm_0ysFYjRVnPwCJHE7v7uF_l1hI6qi6QBsA
     * @throws WeixinException
     */
    public static ReOpenAccessToken getAccessTokenByCode(String appid, String code, String grant_type, String component_appid, String component_access_token) throws WeixinException {
        String requestUrl = get_access_token_bycode_url.replace("COMPONENT_APPID", component_appid).replace("COMPONENT_ACCESS_TOKEN", component_access_token).replace("authorization_code", grant_type).replace("CODE", code).replace("APPID", appid);
        JSONObject result = WxHttpUtils.httpRequest(requestUrl, "GET", null);
        System.out.println("getAccessTokenByCode:" + result);
        if (result.containsKey("errcode")) {
            throw new WeixinException("获取第三方平台access_token！errcode=" + result.getString("errcode") + ",errmsg = " + result.getString("errmsg"));
        }
        return JSONObject.toJavaObject(result, ReOpenAccessToken.class);
    }


    /**
     * 发送客服消息
     *
     * @param obj
     * @param ACCESS_TOKEN
     * @return
     */
    public static String sendMessage(Map<String, Object> obj, String ACCESS_TOKEN) {
        String jsonString = JSONObject.toJSONString(obj);
        System.out.println("--------发送客服消息---------json-----" + jsonString);
        // 调用接口获取access_token
        String url = send_message_url.replace("ACCESS_TOKEN", ACCESS_TOKEN);
        JSONObject jsonObject = WxHttpUtils.httpRequest(url, "POST", jsonString);
        return jsonObject.toString();
    }
}
